package com.springboot.dubbo.book.provider;

import com.springboot.dubbo.book.api.IBookProvider;
import com.springboot.dubbo.book.service.CallRingMsgServiceImpl;
import com.springboot.dubbo.user.api.IUserProvider;
import io.seata.spring.annotation.GlobalTransactional;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.apache.dubbo.config.annotation.Method;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @ClassName BookService
 * @Description: 微服务提供者，可以部署多态进行分布式集群
 * @Author 杨冬冬
 * @Date 2021/6/29 0029 13:54
 **/
@Component
@DubboService(group = "dubbo-demo", version = "0.0.1")
public class BookProvider implements IBookProvider {

    /*
     * dubbo 有超时重试机制，这里需要给insert指定上不需要重试，避免因执行超时造成的事务回滚失败
     *
     * 配置原则：
     *  dubbo推荐在Provider上尽量多配置Consumer端属性：
     *       作为服务的提供者，比服务方更清楚服务性能的参数，如调用时间，合理的重试次数等，所以这些参数应尽量配置在服务的提供者方；
     *       在provider配置后，Consumer不配置则会使用provider的配置值，即provider的配置会作为consumer配置的缺省值。如果使用consumer的全局配置，这对于provider是不可控的，并且是不合理的。
     *
     * 覆盖规则：
     *      方法级的配置的优先级>接口级配置的优先级>全局级配置的优先级，即遵循就近原则，以此为基础；
     *      在同级情况下，消费者的优先级大于提供者的优先级；
     *      优先级高的会将优先级低的覆盖；
     **/
    @DubboReference(group = "dubbo-demo", version = "0.0.2", methods = {@Method(name = "insert", timeout = 1000, retries = 0)})
    private IUserProvider userProvider;

    @Autowired
    private CallRingMsgServiceImpl callRingMsgService;

    /*
     * 普通测试
     **/
    @Override
    public String list() {
        return "能调用了啊...";
    }

    /*
     * 微服务相互调用测试
     **/
    @Override
    public String userBook() {
        return userProvider.getUser().toString() + "的输啊啊";
        //return "用户的书";
    }

    /*
     * 分布式事务测试
     * @GlobalTransactional 就是开启了seata分布式事务，利用的就是spring aop的思想
     **/
    @Override
    @GlobalTransactional
    public void insert() throws Exception {
        String xid = io.seata.core.context.RootContext.getXID();
        System.out.println(xid);
        callRingMsgService.insert();
        userProvider.insert();
    }
}

